
(defrule Horoscope_start
	(declare (salience -7))
    (logical (start_horo)) 
=>
        (assert (UI-state (display Horoscope_start)
                     (relation-asserted horo_yes)
                     (response y)    
                     (valid-answers y n))))

(defrule Final_result
	(declare (salience -12))
    (logical (display_result))
=>
    (assert (UI-state (display DisplayResult)
                     (state final))))

;;=================================END OF QUESTION PART=============================
;;;;;After Hard Constrant, filter our non-necessary facts from horoscope Initial facts
(defrule decrease_facts_horo
    (declare (salience 7))
	(target_gender ?g)
	(target_hard_fact (name ?name1) (gender ?gender) )
	(target_a_fact_bkgd (name ?name2&:(eq ?name1 ?name2)) (category horoscope) (val ?horo) )
=>	
	(assert (target_a_current_bkgd (name ?name2) (category horoscope) (val ?horo) ))
	(assert (current_goal (category horoscope) (name ?name2) (cf 0.5)))
)


;;;;;delete all initial appearance facts(not required anymore)
(defrule delete_initial_facts_horo
	(declare (salience 6))
    (target_gender ?g)
	?f1 <-(target_a_fact_bkgd (name ?name) (category horoscope) (val ?horo) )
=>
	(retract ?f1)
)

;;;;;;;;follow the horoscope rules to adjust the cf
(defrule horo_define
	(declare (salience 7))
	(constellation ?con)
=> (switch ?con
	(case Aries then (assert (source_horo 1)))
	(case Taurus then (assert (source_horo 2)))
	(case Gemini then (assert (source_horo 3)))
	(case Cancer then (assert (source_horo 4)))
	(case Leo then (assert (source_horo 5)))
	(case Virgo then (assert (source_horo 6)))
	(case Libra then (assert (source_horo 7)))
	(case Scorpio then (assert (source_horo 8)))
	(case Sagittarius then (assert (source_horo 9)))
	(case Capricorn then (assert (source_horo 10)))
	(case Aquarius then (assert (source_horo 11)))
	(case Pisces then (assert (source_horo 12)))
	)	
)

(defrule horo_filter
	(declare (salience 7))
;    (logical (horo_yes y))
	(source_horo ?s_horo)
	(target_a_current_bkgd (name ?name) (category horoscope) (val ?t_horo) )
=>(switch ?s_horo
    (case 1 then (switch ?t_horo
                      (case 3 then (assert (working_goal (category horoscope) (name ?name) (cf  -0.75))))
                      (case 4 then (assert (working_goal (category horoscope) (name ?name) (cf  -0.75))))
                      (case 5 then (assert (working_goal (category horoscope) (name ?name) (cf  0.75))))
                      (case 6 then (assert (working_goal (category horoscope) (name ?name) (cf  -0.75))))
                      (case 8 then (assert (working_goal (category horoscope) (name ?name) (cf  0.75))))
                      (case 9 then (assert (working_goal (category horoscope) (name ?name) (cf  -0.75))))
                      (case 10 then (assert (working_goal (category horoscope) (name ?name) (cf  -0.75))))
                      (default (assert (working_goal (category horoscope) (name ?name) (cf  0.1))))                                                            
     ))
    (case 2 then (switch ?t_horo
                      (case 3 then (assert (working_goal (category horoscope) (name ?name) (cf  -0.75))))
                      (case 4 then (assert (working_goal (category horoscope) (name ?name) (cf  0.75))))
                      (case 6 then (assert (working_goal (category horoscope) (name ?name) (cf  0.75))))
                      (case 7 then (assert (working_goal (category horoscope) (name ?name) (cf  -0.75))))
                      (case 10 then (assert (working_goal (category horoscope) (name ?name) (cf  0.75))))
                      (case 11 then (assert (working_goal (category horoscope) (name ?name) (cf  -0.75))))
                      (default (assert (working_goal (category horoscope) (name ?name) (cf  0.1))))    
     ))
    (case 3 then (switch ?t_horo
                      (case 1 then (assert (working_goal (category horoscope) (name ?name) (cf  0.75))))
                      (case 2 then (assert (working_goal (category horoscope) (name ?name) (cf  -0.75))))
                      (case 5 then (assert (working_goal (category horoscope) (name ?name) (cf  0.75))))
                      (case 7 then (assert (working_goal (category horoscope) (name ?name) (cf  0.75))))
                      (case 9 then (assert (working_goal (category horoscope) (name ?name) (cf  0.75))))
                      (case 10 then (assert (working_goal (category horoscope) (name ?name) (cf  -0.75))))
                      (case 11 then (assert (working_goal (category horoscope) (name ?name) (cf  0.75))))
                      (case 12 then (assert (working_goal (category horoscope) (name ?name) (cf  -0.75))))
                      (default (assert (working_goal (category horoscope) (name ?name) (cf  0.1))))
     ))
    (case 4 then (switch ?t_horo
                      (case 2 then (assert (working_goal (category horoscope) (name ?name) (cf  0.75))))
                      (case 5 then (assert (working_goal (category horoscope) (name ?name) (cf  0.75))))
                      (case 6 then (assert (working_goal (category horoscope) (name ?name) (cf  0.75))))
                      (case 8 then (assert (working_goal (category horoscope) (name ?name) (cf  0.75))))
                      (case 9 then (assert (working_goal (category horoscope) (name ?name) (cf  -0.75))))
                      (case 10 then (assert (working_goal (category horoscope) (name ?name) (cf  0.75))))
                      (case 11 then (assert (working_goal (category horoscope) (name ?name) (cf  -0.75))))
                      (default (assert (working_goal (category horoscope) (name ?name) (cf  0.1)))) 
     ))
    (case 5 then (switch ?t_horo
                      (case 1 then (assert (working_goal (category horoscope) (name ?name) (cf  0.75))))
                      (case 2 then (assert (working_goal (category horoscope) (name ?name) (cf  -0.75))))
                      (case 3 then (assert (working_goal (category horoscope) (name ?name) (cf  0.75))))
                      (case 4 then (assert (working_goal (category horoscope) (name ?name) (cf  0.75))))
                      (case 6 then (assert (working_goal (category horoscope) (name ?name) (cf  0.75))))
                      (case 7 then (assert (working_goal (category horoscope) (name ?name) (cf  -0.75))))
                      (case 8 then (assert (working_goal (category horoscope) (name ?name) (cf  0.75))))
                      (case 10 then (assert (working_goal (category horoscope) (name ?name) (cf  -0.75))))
                      (case 11 then (assert (working_goal (category horoscope) (name ?name) (cf  -0.75))))
                      (case 12 then (assert (working_goal (category horoscope) (name ?name) (cf  -0.75))))
                      (default (assert (working_goal (category horoscope) (name ?name) (cf  0.1))))
     ))
    (case 6 then (switch ?t_horo
                      (case 1 then (assert (working_goal (category horoscope) (name ?name) (cf  -0.75))))
                      (case 2 then (assert (working_goal (category horoscope) (name ?name) (cf  0.75))))
                      (case 5 then (assert (working_goal (category horoscope) (name ?name) (cf  -0.75))))
                      (case 10 then (assert (working_goal (category horoscope) (name ?name) (cf  0.75))))
                      (case 12 then (assert (working_goal (category horoscope) (name ?name) (cf  0.75))))
                      (default (assert (working_goal (category horoscope) (name ?name) (cf  0.1)))) 
     ))
    (case 7 then (switch ?t_horo
                      (case 1 then (assert (working_goal (category horoscope) (name ?name) (cf  -0.75))))
                      (case 3 then (assert (working_goal (category horoscope) (name ?name) (cf  0.75))))
                      (case 4 then (assert (working_goal (category horoscope) (name ?name) (cf  -0.75))))
                      (case 5 then (assert (working_goal (category horoscope) (name ?name) (cf  0.75))))
                      (case 8 then (assert (working_goal (category horoscope) (name ?name) (cf  -0.75))))
                      (case 10 then (assert (working_goal (category horoscope) (name ?name) (cf  -0.75))))
                      (case 11 then (assert (working_goal (category horoscope) (name ?name) (cf  0.75))))
                      (default (assert (working_goal (category horoscope) (name ?name) (cf  0.1)))) 
     ))
    (case 8 then (switch ?t_horo
                      (case 2 then (assert (working_goal (category horoscope) (name ?name) (cf  0.75))))
                      (case 4 then (assert (working_goal (category horoscope) (name ?name) (cf  0.75))))
                      (case 6 then (assert (working_goal (category horoscope) (name ?name) (cf  0.75))))
                      (case 10 then (assert (working_goal (category horoscope) (name ?name) (cf  0.75))))
                      (case 12 then (assert (working_goal (category horoscope) (name ?name) (cf  0.75))))
                      (default (assert (working_goal (category horoscope) (name ?name) (cf  0.1)))) 
     ))
    (case 9 then (switch ?t_horo
                      (case 1 then (assert (working_goal (category horoscope) (name ?name) (cf  0.75))))
                      (case 2 then (assert (working_goal (category horoscope) (name ?name) (cf  -0.75))))
                      (case 3 then (assert (working_goal (category horoscope) (name ?name) (cf  0.75))))
                      (case 4 then (assert (working_goal (category horoscope) (name ?name) (cf  -0.75))))
                      (case 5 then (assert (working_goal (category horoscope) (name ?name) (cf  0.75))))
                      (case 6 then (assert (working_goal (category horoscope) (name ?name) (cf  -0.75))))
                      (case 7 then (assert (working_goal (category horoscope) (name ?name) (cf  0.75))))
                      (case 8 then (assert (working_goal (category horoscope) (name ?name) (cf  -0.75))))
                      (case 10 then (assert (working_goal (category horoscope) (name ?name) (cf  -0.75))))
                      (case 11 then (assert (working_goal (category horoscope) (name ?name) (cf  0.75))))
                      (default (assert (working_goal (category horoscope) (name ?name) (cf  0.1))))
     ))
    (case 10 then (switch ?t_horo
                      (case 1 then (assert (working_goal (category horoscope) (name ?name) (cf  -0.75))))
                      (case 2 then (assert (working_goal (category horoscope) (name ?name) (cf  0.75))))                     
                      (case 4 then (assert (working_goal (category horoscope) (name ?name) (cf  0.75))))
                      (case 5 then (assert (working_goal (category horoscope) (name ?name) (cf  -0.75))))
                      (case 6 then (assert (working_goal (category horoscope) (name ?name) (cf  0.75))))
                      (case 7 then (assert (working_goal (category horoscope) (name ?name) (cf  0.75))))
                      (case 9 then (assert (working_goal (category horoscope) (name ?name) (cf  -0.75))))
                      (case 12 then (assert (working_goal (category horoscope) (name ?name) (cf  0.75))))
                      (default (assert (working_goal (category horoscope) (name ?name) (cf  0.1))))
     ))
    (case 11 then (switch ?t_horo
                      (case 2 then (assert (working_goal (category horoscope) (name ?name) (cf  -0.75))))
                      (case 3 then (assert (working_goal (category horoscope) (name ?name) (cf  0.75))))
                      (case 4 then (assert (working_goal (category horoscope) (name ?name) (cf  -0.75))))
                      (case 6 then (assert (working_goal (category horoscope) (name ?name) (cf  -0.75))))
                      (case 7 then (assert (working_goal (category horoscope) (name ?name) (cf  0.75))))
                      (case 8 then (assert (working_goal (category horoscope) (name ?name) (cf  -0.75))))
                      (case 10 then (assert (working_goal (category horoscope) (name ?name) (cf  -0.75))))
                      (case 11 then (assert (working_goal (category horoscope) (name ?name) (cf  0.75))))
                      (case 12 then (assert (working_goal (category horoscope) (name ?name) (cf  -0.75))))
                      (default (assert (working_goal (category horoscope) (name ?name) (cf  0.1))))
     ))
    (case 12 then (assert (working_goal (category horoscope) (name ?name) (cf  0.75)))
     )
  )
	
)

;;;;;;;;;;;;;Transfer the horoscope cf to the total 4 category cf facts.
(defrule horoscopeto4
;    (declare (salience -9))
;	(logical (horo_yes y))
	(current_goal (category horoscope) (name ?name_horo) (cf ?cf_horo))
	?f1 <- (person_CFs (name ?name2&:(eq ?name_horo ?name2)) (appearance-cf ?a-cf) (edujob-cf ?e-cf) (character-cf ?c-cf) (horoscope-cf ?h-cf&:(neq ?h-cf ?cf_horo)))
=>
	(assert (person_CFs (name ?name2) (appearance-cf ?a-cf) (edujob-cf ?e-cf) (character-cf ?c-cf) (horoscope-cf ?cf_horo)))
	(retract ?f1)
)

(defrule add_horoscope_reason
    (declare (salience 10))
    (current_goal (category horoscope) (name ?name_horo) (cf ?cf_horo))
    (test (>= 0.75 ?cf_horo))
    (person_CFs (name ?name2&:(eq ?name_horo ?name2)) (appearance-cf ?a-cf) (edujob-cf ?e-cf) (character-cf ?c-cf) (horoscope-cf ?h-cf&:(eq ?h-cf ?cf_horo)))
=>    
         (assert (reason (name ?name2) (category horoscope) (subcategory "Horoscope")(reason "Your horoscopes match with each other")))
)





;;;;;;;;End of Horoscope Part;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;



;;;;;;;;;;;;;caculate the final cf based on 4 category(method to be developed futher);;;;;;;;;
(defrule average
	(declare (salience -10))
    (horo_yes y)
	(current_place ?cp)
	?f1 <- (person_CFs (name ?name) (appearance-cf ?a-cf) (edujob-cf ?e-cf) (character-cf ?c-cf) (horoscope-cf ?h-cf))
=>
	(assert (final_1 (name ?name) (cf (/ (+ ?a-cf (+ ?e-cf (+ ?c-cf ?h-cf))) 4)) (place (+ ?cp 1))))
	(assert (current_place (+ ?cp 1)))
	(assert (testing ?name ?a-cf ?e-cf ?c-cf ?h-cf))
	(retract ?f1)

)	

;;;;;;;;;;;;;;;;;;;;;;;;;;Combine categories;;;;;;;;;;;;;;;;;;;;;;;;;;
;;step 0: initiate 
;(defrule initiate_final
;	(declare (salience -10))
;    (horo_yes ?h)
;	(person_CFs (name ?name) (appearance-cf ?a-cf) (edujob-cf ?e-cf) (character-cf ?c-cf) (horoscope-cf ?h-cf))
;=>
;	(assert (current_goal (category final) (name ?name) (cf 0)))
;    
;)

;;step 1: calculate appr
;(defrule calculate_final_appr
;	(declare (salience -10))
;    (horo_yes ?h)
;	(person_CFs (name ?name) (appearance-cf ?a-cf) (edujob-cf ?e-cf) (character-cf ?c-cf) (horoscope-cf ?h-cf))
;    (not (calculate_final ?name appr))
;=>
;	(assert (working_goal (category final) (name ?name) (cf (* 0.4 ?a-cf))))
;    (assert (calculate_final ?name appr))
;)

;;step 2: calculate edujob
;(defrule calculate_final_edu
;	(declare (salience -10))
;    (horo_yes ?h)
;	(person_CFs (name ?name) (appearance-cf ?a-cf) (edujob-cf ?e-cf) (character-cf ?c-cf) (horoscope-cf ?h-cf))
;    (not (calculate_final ?name education))
;=>
;	(assert (working_goal (category final) (name ?name) (cf (* 0.4 ?e-cf))))
;    (assert (calculate_final ?name education))
;)

;;step 3: calculate character
;(defrule calculate_final_char
;	(declare (salience -10))
;    (horo_yes ?h)
	(person_CFs (name ?name) (appearance-cf ?a-cf) (edujob-cf ?e-cf) (character-cf ?c-cf) (horoscope-cf ?h-cf))
;    (not (calculate_final ?name character))
;=>
;	(assert (working_goal (category final) (name ?name) (cf (* 0.4 ?c-cf))))
;    (assert (calculate_final ?name character))
;)

;;step 4: calculate horo
;(defrule calculate_final_horo
;	(declare (salience -10))
;    (horo_yes y)
;	(person_CFs (name ?name) (appearance-cf ?a-cf) (edujob-cf ?e-cf) (character-cf ?c-cf) (horoscope-cf ?h-cf))
;    (not (calculate_final ?name horoscope))   
;=>
;	(assert (working_goal (category final) (name ?name) (cf (* 0.4 ?h-cf))))
;    (assert (calculate_final ?name horoscope))
;)


;(defrule retract_final
;    (declare (salience -10))
;    ?f <- (person_CFs (name ?name) (appearance-cf ?a-cf) (edujob-cf ?e-cf) (character-cf ?c-cf) (horoscope-cf ?h-cf))
;    (current_goal (category final) (name ?name) (cf ?cf))
;    (calculate_final ?name appr)
;    (calculate_final ?name education)
;    (calculate_final ?name character)
;    (calculate_final ?name horoscope)
;    ?f2 <- (current_place ?cp)
;=>    (retract ?f)
;    (retract ?f2)
;    (assert (current_place (+ 1 ?cp)))
;    (assert (final_1 (name ?name) (cf ?cf) (place (+ ?cp 1))))
;)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;end;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


;;;;;;;;;;;;;caculate the final cf based on 4 category(method to be developed futher);;;;;;;;;
(defrule average_without_horoscope
	(declare (salience -10))
    (horo_yes n)	
	(current_place ?cp)
	?f1 <- (person_CFs (name ?name) (appearance-cf ?a-cf) (edujob-cf ?e-cf) (character-cf ?c-cf) (horoscope-cf ?h-cf))
=>
	(assert (final_1 (name ?name) (cf (/ (+ ?a-cf (+ ?e-cf ?c-cf)) 3)) (place (+ ?cp 1))))
	(assert (current_place (+ ?cp 1)))
	(assert (testing ?name ?a-cf ?e-cf ?c-cf ?h-cf));;testing purpose, will delete later
	(retract ?f1)

)	
;;;;;;;;;;;;;;;;;end;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(defrule bubble_sort
	(declare (salience -11))
	?f1<-(final_1 (name ?name1) (cf ?cf1) (place ?p1))
	?f2<-(final_1 (name ?name2) (cf ?cf2) (place ?p2))
    (test (< ?cf1 ?cf2))
    (test (= (+ ?p1 1) ?p2))   
=>
    (retract ?f1 ?f2)
    (assert (final_1 (name ?name1) (cf ?cf1) (place ?p2))
            (final_1 (name ?name2) (cf ?cf2) (place ?p1)))
;;    (assert (display_result))
)

(defrule create_fina0
	(declare (salience -12))
	(final_1 (name ?name1) (cf ?cf1&:(< ?cf1 0.6)) (place  ?p&:(= ?p 1)))
=>
	(assert (result non))
		(assert (final (name ?name1) (cf (integer (* ?cf1 100))) (place 1)))
)

(defrule create_final
	(declare (salience -12))
	(final_1 (name ?name1) (cf ?cf1&:(>= ?cf1 0.6)) (place  ?p&:(= ?p 1)))
=>
	(assert (final (name ?name1) (cf (integer (* ?cf1 100))) (place 1)))
)

(defrule create_fina2
	(declare (salience -13))
	(final_1 (name ?name1) (cf ?cf1&:(>= ?cf1 0.6)) (place  ?p&:(= ?p 2)))
=>
	(assert (final (name ?name1) (cf (integer (* ?cf1 100))) (place 2)))
)

(defrule create_fina3
	(declare (salience -14))
	(final_1 (name ?name1) (cf ?cf1&:(>= ?cf1 0.6)) (place  ?p&:(= ?p 3)))
=>
	(assert (final (name ?name1) (cf (integer (* ?cf1 100))) (place 3)))
)

(defrule create_fina4
	(declare (salience -15))
	(final_1 (name ?name1) (cf ?cf1&:(>= ?cf1 0.6)) (place  ?p&:(= ?p 4)))
=>
	(assert (final (name ?name1) (cf (integer (* ?cf1 100))) (place 4)))
)


;;;;;;;;;;;;;;;output;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defrule output
	(declare (salience -16))
	(final (name ?name1) (cf ?cf) (place ?p1&:(= ?p1 1)))
=>	

		(assert (display_result))
)
	


(defrule output_none
	(declare (salience -16))
	(result non)

=>	
		(assert (display_result))
)


;;;;;;;;;;;;;;;;;;end of output;;;;;;;;;;;;;;;;;;;;;;;;;